package cn.echo.sharding.aspectj;

import cn.echo.sharding.annotation.HintMasterRoute;
import org.apache.shardingsphere.api.hint.HintManager;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

import java.lang.reflect.Method;

/**
 * 强制master数据源实现类
 * @author lonyee
 */
@Aspect
public class HintMasterRouteAspect extends AbstractShardingAspectSupport{

    public HintMasterRouteAspect() {
    }

    @Pointcut("@annotation(cn.echo.sharding.annotation.HintMasterRoute)")
    public void masterRouteAnnotationPointcut() { }

    @Around("masterRouteAnnotationPointcut()")
    public Object invokeMasterRoute(ProceedingJoinPoint pjp) throws Throwable {
        Method originMethod = this.resolveMethod(pjp);
        HintMasterRoute annotation = (HintMasterRoute) originMethod.getAnnotation(HintMasterRoute.class);
        if (annotation == null) {
            throw new IllegalStateException("Wrong state for HintMasterRoute annotation");
        }
        //非强制 走默认策略
        if (!annotation.isMasterOnly()) {
            return pjp.proceed();
        }

        log.info("hint route master datasource.");
        HintManager.clear();
        try (HintManager hintManager = HintManager.getInstance()) {
            hintManager.setMasterRouteOnly();
            return pjp.proceed();
        }
    }

}
